package com.baigao.springboot.util;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Properties;

import org.junit.Test;
import org.slf4j.*;

public class FileUtil {
	private final static Logger log = LoggerFactory.getLogger(FileUtil.class);

	public static String REAL_PATH = null;
	static {
		if (Thread.currentThread().getContextClassLoader().getResource("/") != null) {
			REAL_PATH = Thread.currentThread().getContextClassLoader().getResource("/").getPath().replace("%20", " ");
		}
		else {
			REAL_PATH = Thread.currentThread().getContextClassLoader().getResource("").getPath().replace("%20", " ");
		}
	}

	/**
	 * 读取properties文件
	 * 
	 * @param propsFile 文件路径，相对路径于com 同级
	 * @return
	 */
	public static Properties loadProperties(String propsFile) {

		Properties props = new Properties();
		InputStream is = null;
		try {
			is = new BufferedInputStream(new FileInputStream(REAL_PATH + propsFile));
			props.load(is);
			is.close();
			log.info("loadProperties OK!");
			log.info("Properties path = " + REAL_PATH + propsFile);
		}
		catch (Exception e) {
			log.error("CuteMonitor FileUtil || Unable to load the properties file:" + e.getMessage());
			log.error("Properties path = " + REAL_PATH + propsFile);
			try {
				is.close();
			}
			catch (IOException e1) {
				e1.printStackTrace();
			}
		}
		return props;
	}

	/**
	 * 读取路径当前文件夹内的音乐文件列表
	 * 
	 * @param path
	 * @return
	 */
	public static List<String> findMusicFiles(String path) {
		File musicFile = new File(path);
		List<String> musicFullPaths = new ArrayList<String>();
		if (musicFile.exists()) {
			File[] musics = musicFile.listFiles();
			for (File music : musics) {
				String musicName = music.getName();
				int i = musicName.lastIndexOf(".");
				String end = musicName.substring(i + 1);
				if (end.equals("wav") || end.equals("mp3") || end.equals("wma")) {
					musicFullPaths.add(musicName);
				}
			}
		}
		return musicFullPaths;
	}

	/**
	 * 读取文件内容
	 * 
	 * @param filePath 文件路径
	 * @param charsetName 文件编码方式
	 * @return
	 */
	public static String readFile(String filePath, String charsetName) {
		StringBuffer sb = new StringBuffer();
		BufferedReader br = null;
		try {
			br = new BufferedReader(new InputStreamReader(new FileInputStream(filePath), charsetName));
			String data = null;
			while ((data = br.readLine()) != null) {
				sb.append(data);
				sb.append("<br/>");

			}
		}
		catch (Exception e) {
		}
		finally {
			try {
				br.close();
			}
			catch (Exception e) {
			}

		}
		return sb.toString();
	}

	/**
	 * 读取文件内容
	 * 
	 * @param filePath 文件路径
	 * @param charsetName 文件编码方式
	 * @return
	 */
	public static String readFile(String filePath, String charsetName, long lineNow, long lineEnd) {
		StringBuffer sb = new StringBuffer();
		BufferedReader br = null;
		try {
			br = new BufferedReader(new InputStreamReader(new FileInputStream(filePath), charsetName));
			String data = null;
			int i = 0;
			while ((data = br.readLine()) != null) {
				if (i <= lineEnd && i >= lineNow) {
					sb.append(data);
					sb.append("<br/>");
				}
				i++;
			}
		}
		catch (Exception e) {
		}
		finally {
			try {
				br.close();
			}
			catch (Exception e) {
			}
		}
		return sb.toString();
	}

	/**
	 * 读取文件内容
	 * 
	 * @param filePath 文件路径
	 * @param charsetName 文件编码方式
	 * @return
	 */
	public static long getFileLine(String filePath, String charsetName) {
		BufferedReader br = null;
		int i = 0;
		try {
			br = new BufferedReader(new InputStreamReader(new FileInputStream(filePath), charsetName));
			while (br.readLine() != null) {
				i++;
			}
		}
		catch (Exception e) {
		}
		finally {
			try {
				br.close();
			}
			catch (Exception e) {
			}

		}
		return i;
	}

	/**
	 * 保存文件
	 * 
	 * @param stream 内容
	 * @param path 文件路径
	 * @param filename 文件名
	 * @throws IOException
	 */
	public static void SaveFileFromInputStream(InputStream stream, String path, String filename) throws IOException {
		FileOutputStream fs = new FileOutputStream(path + "/" + filename);
		byte[] buffer = new byte[(1024 * 1024)*100];
		int bytesum = 0;
		int byteread = 0;
		while ((byteread = stream.read(buffer)) != -1) {
			bytesum += byteread;
			fs.write(buffer, 0, bytesum);
			fs.flush();
		}
		fs.close();
		stream.close();
	}

	/**
	 * <p>
	 * Description:[删除文件（文件夹）]
	 * </p>
	 * 
	 * @param file
	 */
	public static void deleteFile(File file) {
		if (file.exists()) {
			if (file.isFile()) {
				file.delete();
			}
			else if (file.isDirectory()) {
				File files[] = file.listFiles();
				for (int i = 0; i < files.length; i++) {
					deleteFile(files[i]);
				}
			}
			file.delete();
		}
	}
	
	/**
	 * <p>
	 * Description:[获取hash值。 hashType的值 ： "MD5","SHA1","SHA-256","SHA-384", "SHA-512"]
	 * 
	 * 
	 * </p>
	 * 
	 * Created by [Administrator] [2018年9月19日]
	 * Midified by [修改人] [修改时间]
	 * @param fileName
	 * @param hasType
	 * @return
	 */
	public static String getHash(String fileName, String hasType) {
		MessageDigest md5 = null;
		try {
			md5 = MessageDigest.getInstance(hasType);
			FileInputStream fis = new FileInputStream(fileName);
			File file = new File(fileName);
			byte buffer[] = new byte[(int)file.length()];
			for (int numRead = 0; (numRead = fis.read(buffer)) > 0;) {
				md5.update(buffer, 0, numRead);
			}
			
			fis.close();
		} catch (Exception e) {
			e.printStackTrace();
			log.error("压缩文件hash异常！");
		}
		
		return toHexString(md5.digest());
	}

	private static String toHexString(byte[] digest) {
		StringBuilder strinBuilder = new StringBuilder("");
		
		if(digest == null || digest.length <= 0) {
			return null;
		}
		
		for (int i = 0; i < digest.length; i++) {
			int v = digest[i] & 0xFF;
			String hv = Integer.toHexString(v);
			
			if(hv.length() < 2) {
				strinBuilder.append(0);
			}
			strinBuilder.append(hv);
		}
		
		return strinBuilder.toString();
	}
	
	/**
     * 获取文件夹下所有文件的名称 + 模糊查询（当不需要模糊查询时，queryStr传空或null即可）
     * 1.当路径不存在时，map返回retType值为1
     * 2.当路径为文件路径时，map返回retType值为2，文件名fileName值为文件名
     * 3.当路径下有文件夹时，map返回retType值为3，文件名列表fileNameList，文件夹名列表folderNameList
     * @param folderPath 路径
     * @param queryStr 模糊查询字符串
     * @return
     */
    public static HashMap<String, Object> getFilesName(String folderPath , String queryStr) {
        HashMap<String, Object> map = new HashMap<String, Object>();
        List<String> fileNameList = new ArrayList<String>();//文件名列表
        List<String> folderNameList = new ArrayList<String>();//文件夹名列表
        File f = new File(folderPath);
        if (!f.exists()) { //路径不存在
            map.put("retType", "1");
        }else{
            boolean flag = f.isDirectory();
            if(flag==false){ //路径为文件
                map.put("retType", "2");
                map.put("fileName", f.getName());
            }else{ //路径为文件夹
                map.put("retType", "3");
                File fa[] = f.listFiles();
                queryStr = queryStr==null ? "" : queryStr;//若queryStr传入为null,则替换为空（indexOf匹配值不能为null）
                for (int i = 0; i < fa.length; i++) {
                    File fs = fa[i];
                    if(fs.getName().indexOf(queryStr)!=-1){
                         if (fs.isDirectory()) {
                             folderNameList.add(fs.getName());
                         } else {
                             fileNameList.add(fs.getName());
                         }
                     }
                }
                map.put("fileNameList", fileNameList);
                map.put("folderNameList", folderNameList);
            }
        }
        return map;
    }
    
    /**
	 * 读取路径当前文件夹内的后缀名文件列表
	 * 
	 * @param path
	 * @param suffixs 后缀名数组
	 * @return
	 */
	public static List<String> findFiles(String path, String[] suffixs) {
		File paredsuffixFile = new File(path);
		List<String> musicFullPaths = new ArrayList<String>();
		if (paredsuffixFile.exists()) {
			File[] musics = paredsuffixFile.listFiles();
			for (File music : musics) {
				String musicName = music.getName();
				int i = musicName.lastIndexOf(".");
				String end = musicName.substring(i + 1);
				for (int j = 0; j < suffixs.length; j++) {
					if (end.equals(suffixs[j])) {
						musicFullPaths.add(musicName);
					}
				}
			}
		}
		return musicFullPaths;
	}
	
	/**
	 * <p>
	 * Description:[服务器端图片删除操作]
	 * </p>
	 * 
	 * Created by [lqw] [2014年11月24日]
	 * Midified by [修改人] [修改时间]
	 * @param actionPath
	 * @param filePath
	 * @return
	 */
	public static String deleteFiles(String actionPath , String filePath) {
		String msg = "";
		String path = actionPath + File.separator + filePath;
		File deleteFile = new File(path);
		if (deleteFile.isFile() && deleteFile.exists()) {
			deleteFile.delete();
		}else{
			msg = "文件不存在！";
		}
		return msg;
	}
	
	@Test
	public void testName() throws Exception {
		File file = new File("d://temp//test.xls");
		System.out.println("path===="+file.toString());
		System.out.println("size===="+file.length());
		System.out.println("name===="+file.getName());
		System.out.println("hash===="+getHash(file.toString(), "SHA1"));
		
		
		
//		测试结果为：
//
//		{
//		　　retType=3, 
//		　　folderNameList=[convert, document], 
//		　　fileNameList=[license.properties, selfLicense.properties, test1.txt]
//		}
		 HashMap<String,Object> filesName = getFilesName("D:/test", "t");
	     System.out.println(filesName);
	}
}
